﻿bob.ns.setNs('bob.utils.tests', {

    TestUtils: function () {

        this.test_isUndefined = function () {

            bob.assert.isTrue(bob.utils.isUndefined(undefined), '1');
            bob.assert.isFalse(bob.utils.isUndefined(null), '2');
            bob.assert.isFalse(bob.utils.isUndefined(false), '3');
            bob.assert.isFalse(bob.utils.isUndefined(0), '4');
            bob.assert.isFalse(bob.utils.isUndefined(''), '5');
            bob.assert.isFalse(bob.utils.isUndefined(' '), '5.1');
            bob.assert.isFalse(bob.utils.isUndefined('undefined'), '5.2');
            bob.assert.isFalse(bob.utils.isUndefined({}), '6');
            bob.assert.isFalse(bob.utils.isUndefined({ toString: function () { return undefined; } }), '7');
            bob.assert.isFalse(bob.utils.isUndefined({ toString: function () { return 'undefined'; } }), '8');
            bob.assert.isFalse(bob.utils.isUndefined(true), '9');
            bob.assert.isFalse(bob.utils.isUndefined(1), '10');
            bob.assert.isFalse(bob.utils.isUndefined({ a: 1 }), '11');
            bob.assert.isFalse(bob.utils.isUndefined('123'), '12');

        };

        this.test_isNull = function () {

            bob.assert.isTrue(bob.utils.isNull(null), '1');
            bob.assert.isFalse(bob.utils.isNull(undefined), '2');
            bob.assert.isFalse(bob.utils.isNull(false), '3');
            bob.assert.isFalse(bob.utils.isNull(0), '4');
            bob.assert.isFalse(bob.utils.isNull(''), '5');
            bob.assert.isFalse(bob.utils.isNull(' '), '5.1');
            bob.assert.isFalse(bob.utils.isNull('undefined'), '5.2');
            bob.assert.isFalse(bob.utils.isNull({}), '6');
            bob.assert.isFalse(bob.utils.isNull({ toString: function () { return undefined; } }), '7');
            bob.assert.isFalse(bob.utils.isNull({ toString: function () { return 'undefined'; } }), '8');
            bob.assert.isFalse(bob.utils.isNull(true), '9');
            bob.assert.isFalse(bob.utils.isNull(1), '10');
            bob.assert.isFalse(bob.utils.isNull({ a: 1 }), '11');
            bob.assert.isFalse(bob.utils.isNull('123'), '12');
        };

        this.test_isUndefinedOrNull = function () {

            bob.assert.isTrue(bob.utils.isUndefinedOrNull(null), '1');
            bob.assert.isTrue(bob.utils.isUndefinedOrNull(undefined), '2');
            bob.assert.isFalse(bob.utils.isUndefinedOrNull(false), '3');
            bob.assert.isFalse(bob.utils.isUndefinedOrNull(0), '4');
            bob.assert.isFalse(bob.utils.isUndefinedOrNull(''), '5');
            bob.assert.isFalse(bob.utils.isUndefinedOrNull(' '), '5.1');
            bob.assert.isFalse(bob.utils.isUndefinedOrNull('undefined'), '5.2');
            bob.assert.isFalse(bob.utils.isUndefinedOrNull({}), '6');
            bob.assert.isFalse(bob.utils.isUndefinedOrNull({ toString: function () { return undefined; } }), '7');
            bob.assert.isFalse(bob.utils.isUndefinedOrNull({ toString: function () { return 'undefined'; } }), '8');
            bob.assert.isFalse(bob.utils.isUndefinedOrNull(true), '9');
            bob.assert.isFalse(bob.utils.isUndefinedOrNull(1), '10');
            bob.assert.isFalse(bob.utils.isUndefinedOrNull({ a: 1 }), '11');
            bob.assert.isFalse(bob.utils.isUndefinedOrNull('123'), '12');

        };

        this.test_isNullOrWhiteSpace = function () {

            bob.assert.isTrue(bob.utils.isNullOrWhiteSpace(null), '1');
            bob.assert.isTrue(bob.utils.isNullOrWhiteSpace(''), '2');
            bob.assert.isTrue(bob.utils.isNullOrWhiteSpace(undefined), '3');
            bob.assert.isTrue(bob.utils.isNullOrWhiteSpace('    '), '4');

            bob.assert.isFalse(bob.utils.isNullOrWhiteSpace(' _ '), '5');
            bob.assert.isFalse(bob.utils.isNullOrWhiteSpace('_'), '6');
            bob.assert.isFalse(bob.utils.isNullOrWhiteSpace('123'), '6.1');
            bob.assert.isFalse(bob.utils.isNullOrWhiteSpace(false), '7');
            bob.assert.isFalse(bob.utils.isNullOrWhiteSpace(0), '8');
            bob.assert.isFalse(bob.utils.isNullOrWhiteSpace({}), '9');
            bob.assert.isFalse(bob.utils.isNullOrWhiteSpace({ toString: function () { return undefined; } }), '10');
            bob.assert.isFalse(bob.utils.isNullOrWhiteSpace({ toString: function () { return 'undefined'; } }), '11');
            bob.assert.isFalse(bob.utils.isNullOrWhiteSpace(true), '12');
            bob.assert.isFalse(bob.utils.isNullOrWhiteSpace(1), '13');
            bob.assert.isFalse(bob.utils.isNullOrWhiteSpace({ a: 1 }), '14');

            bob.assert.throwsError(function () { bob.utils.isNullOrWhiteSpace(false, true) }, '7-1');
            bob.assert.throwsError(function () { bob.utils.isNullOrWhiteSpace(0, true) }, '8-1');
            bob.assert.throwsError(function () { bob.utils.isNullOrWhiteSpace({}, true) }, '9-1');
            bob.assert.throwsError(function () { bob.utils.isNullOrWhiteSpace({ toString: function () { return undefined; } }, true) }, '10-1');
            bob.assert.throwsError(function () { bob.utils.isNullOrWhiteSpace({ toString: function () { return 'undefined'; } }, true) }, '11-1');
            bob.assert.throwsError(function () { bob.utils.isNullOrWhiteSpace(true, true) }, '12-1');
            bob.assert.throwsError(function () { bob.utils.isNullOrWhiteSpace(1, true) }, '13-1');
            bob.assert.throwsError(function () { bob.utils.isNullOrWhiteSpace({ a: 1 }, true) }, '14-1');

        };

        this.test_clone = function () {
            bob.assert.equals(undefined, bob.utils.clone(undefined), '0');
            bob.assert.equals(null, bob.utils.clone(null), '1');
            bob.assert.equals(12, bob.utils.clone(12), '2');
            bob.assert.equals('asd', bob.utils.clone('asd'), '3');

            //date.
            var obj = new Date();
            var clone = bob.utils.clone(obj);
            bob.assert.isTrue(obj != clone, '4');
            bob.assert.equals(obj, clone, '5');

            //array.
            var obj = [1, 2, 3];
            var clone = bob.utils.clone(obj);
            bob.assert.notEquals(obj, clone, '6');
            bob.assert.isTrue(bob.collections.extensions.equals.call(obj, clone), '7');

            //object.
            var obj = { a: 1, b: 'Bob', c: false };
            var clone = bob.utils.clone(obj);
            bob.assert.notEquals(obj, clone, '8');
            bob.assert.isTrue(bob.collections.extensions.equals.call(obj, clone), '9');
        };

        this.test_clone_DeepCopy = function () {
            var obj = { a: { b: function () { }, c: 1, d: { e: '123', f: function () { } } }, g: [1, 2, 3], h: null, i: undefined };
            var clone = bob.utils.clone(obj, true);

            bob.assert.notEquals(obj, clone, '1');
            bob.assert.isObject(clone.a);
            bob.assert.notEquals(obj.a, clone.a);
            bob.assert.isFunction(clone.a.b);
            bob.assert.equals(obj.a.b, clone.a.b);
            bob.assert.isNumber(clone.a.c);
            bob.assert.equals(obj.a.c, clone.a.c);
            bob.assert.isObject(clone.a.d);
            bob.assert.notEquals(obj.a.d, clone.a.d);
            bob.assert.isTrue(bob.collections.extensions.equals.call(obj.a.d, clone.a.d));
            bob.assert.isArray(clone.g);
            bob.assert.notEquals(obj.g, clone.g);
            bob.assert.isTrue(bob.collections.extensions.equals.call(obj.g, clone.g));
            bob.assert.isNull(clone.h);
            bob.assert.equals(obj.h, clone.h);
            bob.assert.isUndefined(clone.i);
            bob.assert.equals(obj.i, clone.i);
        };

        this.test_extendObject = function () {

            var object = {};

            var fnEquals = function (one, two, oneName, twoName) { return (oneName == twoName) && bob.utils.equals(one, two); };

            bob.utils.extendObject(object, { a: 1 });
            bob.assert.isTrue(bob.collections.extensions.equals.call({ a: 1 }, object, fnEquals));

            bob.utils.extendObject(object, { b: 2 });
            bob.assert.isFalse(bob.collections.extensions.equals.call({ a: 1 }, object, fnEquals));
            bob.assert.isTrue(bob.collections.extensions.equals.call({ a: 1, b: 2 }, object, fnEquals));
            bob.assert.isTrue(bob.collections.extensions.equals.call(bob.utils.extendObject({ a: 1 }, { b: 2 }), object, fnEquals));
            bob.assert.isFalse(bob.collections.extensions.equals.call(bob.utils.extendObject({ b: 1 }, { a: 2 }), object, fnEquals));
            bob.assert.isFalse(bob.collections.extensions.equals.call(bob.utils.extendObject({ b: 2 }, { a: 1 }), object, fnEquals));

        };

        this.test_extendObject_DeepCopy = function () {
            var object = {};
            var extension = { a: { b: function () { }, c: 1, d: { e: '123', f: function () { } } }, g: [1, 2, 3], h: null, i: undefined };

            bob.utils.extendObject(object, extension, true);

            bob.assert.isObject(object);
            bob.assert.isObject(object.a);
            bob.assert.notEquals(extension.a, object.a);
            bob.assert.isFunction(object.a.b);
            bob.assert.equals(extension.a.b, object.a.b);
            bob.assert.isNumber(object.a.c);
            bob.assert.equals(extension.a.c, object.a.c);
            bob.assert.isObject(object.a.d);
            bob.assert.notEquals(extension.a.d, object.a.d);
            bob.assert.isString(object.a.d.e);
            bob.assert.equals(extension.a.d.e, object.a.d.e);
            bob.assert.isFunction(object.a.d.f);
            bob.assert.equals(extension.a.d.f, object.a.d.f);
            bob.assert.isArray(object.g);
            bob.assert.notEquals(extension.g, object.g);
            bob.assert.isTrue(bob.collections.extensions.equals.call(extension.g, object.g));
            bob.assert.equals(extension.h, object.h);
            bob.assert.equals(extension.i, object.i);

        };

        this.test_ifUndefined = function () {
            var testParams = {
                '1': undefined,
                '2': null,
                '3': false,
                '4': 0,
                '5': '',
                '5.1': ' ',
                '5.2': 'undefined',
                '6': {},
                '7': { toString: function () { return undefined; } },
                '8': { toString: function () { return 'undefined'; } },
                '9': true,
                '10': 1,
                '11': { a: 1 },
                '12': '123'
            };

            for (var code in testParams) {
                bob.assert.equals(testParams[code], bob.utils.ifUndefined(undefined, testParams[code]), 'equals: ' + code);
            }

            delete testParams['1'];
            var wrongValue = 123;
            for (var code in testParams) {
                bob.assert.notEquals(wrongValue, bob.utils.ifUndefined(testParams[code], wrongValue), 'not-equals: ' + code);
            }
        };

        this.test_ifNull = function () {
            var testParams = {
                '1': null,
                '2': undefined,
                '3': false,
                '4': 0,
                '5': '',
                '5.1': ' ',
                '5.2': 'undefined',
                '6': {},
                '7': { toString: function () { return undefined; } },
                '8': { toString: function () { return 'undefined'; } },
                '9': true,
                '10': 1,
                '11': { a: 1 },
                '12': '123'
            };

            for (var code in testParams) {
                bob.assert.equals(testParams[code], bob.utils.ifNull(null, testParams[code]), 'equals: ' + code);
            }

            delete testParams['1'];
            var wrongValue = 123;
            for (var code in testParams) {
                bob.assert.notEquals(wrongValue, bob.utils.ifNull(testParams[code], wrongValue), 'not-equals: ' + code);
            }
        };

        this.test_ifUndefinedOrNull = function () {
            var testParams = {
                '1': undefined,
                '2': null,
                '3': false,
                '4': 0,
                '5': '',
                '5.1': ' ',
                '5.2': 'undefined',
                '6': {},
                '7': { toString: function () { return undefined; } },
                '8': { toString: function () { return 'undefined'; } },
                '9': true,
                '10': 1,
                '11': { a: 1 },
                '12': '123'
            };

            for (var code in testParams) {
                bob.assert.equals(testParams[code], bob.utils.ifUndefinedOrNull(undefined, testParams[code]), 'equals: ' + code);
                bob.assert.equals(testParams[code], bob.utils.ifUndefinedOrNull(null, testParams[code]), 'equals: ' + code);
            }

            delete testParams['1'];
            delete testParams['2'];
            var wrongValue = 123;
            for (var code in testParams) {
                bob.assert.notEquals(wrongValue, bob.utils.ifUndefinedOrNull(testParams[code], wrongValue), 'not-equals: ' + code);
                bob.assert.notEquals(wrongValue, bob.utils.ifUndefinedOrNull(testParams[code], wrongValue), 'not-equals: ' + code);
            }
        };

        this.test_ifNullOrWhiteSpace = function () {
            var testParams = {
                '1': null,
                '2': '',
                '3': undefined,
                '4': '    ',

                '5': ' _ ',
                '6': '_',
                '6.1': '123',
                '7': false,
                '8': 0,
                '9': {},
                '10': { toString: function () { return undefined; } },
                '11': { toString: function () { return 'undefined'; } },
                '12': true,
                '13': 1,
                '14': { a: 1 }
            };

            for (var code in testParams) {
                bob.assert.equals(testParams[code], bob.utils.ifNullOrWhiteSpace('', testParams[code]), 'equals: ' + code);
                bob.assert.equals(testParams[code], bob.utils.ifNullOrWhiteSpace(' ', testParams[code]), 'equals: ' + code);
                bob.assert.equals(testParams[code], bob.utils.ifNullOrWhiteSpace('       ', testParams[code]), 'equals: ' + code);
            }

            delete testParams['1'];
            delete testParams['2'];
            delete testParams['3'];
            delete testParams['4'];
            var wrongValue = 123;
            for (var code in testParams) {
                bob.assert.notEquals(wrongValue, bob.utils.ifNullOrWhiteSpace(testParams[code], wrongValue), 'not-equals: ' + code);
                bob.assert.notEquals(wrongValue, bob.utils.ifNullOrWhiteSpace(testParams[code], wrongValue), 'not-equals: ' + code);
                bob.assert.notEquals(wrongValue, bob.utils.ifNullOrWhiteSpace(testParams[code], wrongValue), 'not-equals: ' + code);
            }
        };

        this.test_isDate = function () {

            bob.assert.isTrue(bob.utils.isDate(new Date()), '1');

            bob.assert.isFalse(bob.utils.isDate('10/01/01'), '2');
            bob.assert.isFalse(bob.utils.isDate('10/01/2001'), '3');
            bob.assert.isFalse(bob.utils.isDate(undefined), '4');
            bob.assert.isFalse(bob.utils.isDate(null), '5');
            bob.assert.isFalse(bob.utils.isDate(1), '6');
            bob.assert.isFalse(bob.utils.isDate(true), '7');

        };

        this.test_equals = function () {
            bob.assert.isTrue(bob.utils.equals(undefined, undefined));
            bob.assert.isTrue(bob.utils.equals(null, null));
            bob.assert.isTrue(bob.utils.equals(true, true));
            bob.assert.isTrue(bob.utils.equals(false, false));
            bob.assert.isTrue(bob.utils.equals(1, 1));
            var date = new Date();
            bob.assert.isTrue(bob.utils.equals(date, date));

            bob.assert.isFalse(bob.utils.equals(undefined, null));
            bob.assert.isFalse(bob.utils.equals(null, false));
            bob.assert.isFalse(bob.utils.equals(false, undefined));
            bob.assert.isFalse(bob.utils.equals(1, 1.01));
            var date2 = new Date(); date2.setFullYear(1900);
            bob.assert.isFalse(bob.utils.equals(date, date2));
            var date2 = new Date(date.getTime());
            bob.assert.isTrue(bob.utils.equals(date, date2));


        };

        this.test_equalsAny = function () {
            bob.assert.isTrue(bob.utils.equalsAny(undefined, [undefined]));
            bob.assert.isTrue(bob.utils.equalsAny(null, [1, null, 2]));
            bob.assert.isTrue(bob.utils.equalsAny(true, [true, 'asd']));
            bob.assert.isTrue(bob.utils.equalsAny(false, [1, false]));
            bob.assert.isTrue(bob.utils.equalsAny(1, [1, 1, 1]));
            var date = new Date();
            bob.assert.isTrue(bob.utils.equalsAny(date, [1, date, 0]));

            bob.assert.isFalse(bob.utils.equalsAny(undefined, [null, false, 0]));
            bob.assert.isFalse(bob.utils.equalsAny(null, [false, undefined, 0, 1]));
            bob.assert.isFalse(bob.utils.equalsAny(false, [undefined, null, 1, 0]));
            bob.assert.isFalse(bob.utils.equalsAny(1, [1.01, 1.00011, -1]));
            var date2 = new Date(); date2.setFullYear(1900);
            bob.assert.isFalse(bob.utils.equalsAny(date, [date2, null]));

        };

        this.test_Lazy = function () {
            var runCount = 0;
            var fnCreate = function () {
                runCount++;
                return runCount;
            };

            var lazy = new bob.utils.Lazy(fnCreate);
            var value = lazy.getValue();
            bob.assert.equals(runCount, value);
            bob.assert.equals(1, runCount);
            bob.assert.equals(1, value);

            value = lazy.getValue();
            bob.assert.equals(runCount, value);
            bob.assert.equals(1, value);
        };

        this.test_lazyFunction = function () {
            var runCount = 0;
            var fnCreate = function () {
                runCount++;
                return runCount;
            };

            var lazyFunction = bob.utils.lazyFunction(fnCreate);
            var value = lazyFunction();
            bob.assert.equals(runCount, value);
            bob.assert.equals(1, runCount);
            bob.assert.equals(1, value);

            value = lazyFunction();
            bob.assert.equals(runCount, value);
            bob.assert.equals(1, value);
        };

        this.test_executeUsing = function () {

            bob.assert.throwsError(function () { bob.utils.executeUsing(); });
            bob.assert.throwsError(function () { bob.utils.executeUsing(null); });
            bob.assert.throwsError(function () { bob.utils.executeUsing({}); });
            bob.assert.throwsError(function () { bob.utils.executeUsing({ dispose: function () { } }, null); });

            var disposable = (function () {
                var res = {
                    isDisposed: false,
                    dispose: function () {
                        res.isDisposed = true;
                    }
                };
                return res;
            })();

            var bExec = false;
            bob.utils.executeUsing(disposable, function (d) {
                bob.assert.equals(disposable, d);
                bob.assert.isFalse(disposable.isDisposed);
                bExec = true;
            });

            bob.assert.isTrue(bExec);
            bob.assert.isTrue(disposable.isDisposed);
        };
    }
});
